/*
    Action类似于mutation，不同在于：
      1. Action提交的mutation，而不是直接变更状态
      2. Action可以包含任意异步操作

    
    分发Action
      Action通过store.dispatch('increment')方法触发
      Action支持载荷方式和对象方式进行分发
          // 以载荷形式分发
          store.dispatch('incrementAsync', {
            amount: 10
          })

          // 以对象形式分发
          store.dispatch({
            type: 'incrementAsync',
            amount: 10
          })


      在组件中分发Action
          1. 使用this.$store.dispatch('xxx')
          2. 使用 mapActions 辅助函数将组件的 methods 映射为 store.dispatch 调用（需要先在根节点注入 store）

    Action返回的Promise   


*/

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) { // 直接更改state
      state.count++ 
    }
  },
  actions: {
    increment (context) { // context，与store实例具有相同的方法和属性，但不是store实例本身
      context.commit('increment')
    }
  },
  // 通过参数解构简化写法
  // actions: {
  //   increment ({ commit }) {
  //     commit('increment')
  //   }
  // }

  actions: {
    incrementAsync ({ commit }) {
      setTimeout(() => { // action内部可以进行异步操作
        commit('increment')
      }, 1000)
    }
  }
})

// mapAction
import { mapActions } from 'vuex'

export default {
  // ...
  methods: {
    ...mapActions([
      'increment', // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')`

      // `mapActions` 也支持载荷：
      'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.dispatch('incrementBy', amount)`
    ]),
    ...mapActions({
      add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
    })
  }
}


// action 返回promise
actions: {
  actionA ({ commit }) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        commit('someMutation')
        resolve()
      }, 1000)
    })
  }
}

store.dispatch('actionA').then(() => {
  // ...
})

actions: {
  // ...
  actionB ({ dispatch, commit }) {
    return dispatch('actionA').then(() => {
      commit('someOtherMutation')
    })
  }
}


